#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include "curl/curl.h"
#include "curl.h"

using namespace std;

size_t writer(char *data, size_t size, size_t nmemb, string *writerData)
{
    unsigned long sizes = size * nmemb;
    if (writerData == NULL) return 0;
    writerData->append(data, sizes);
    return sizes;
}

string GetResponseByCurl(const string& url)
{
    CURL *curl;                        //定义CURL类型的指针
    CURLcode code;

    curl = curl_easy_init();        //初始化一个CURL类型的指针
    if(curl != NULL)
    {
        string buffer;
        code = curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        if (code != CURLE_OK)
        {
            fprintf(stderr, "Failed to set 1 [%d]\n", code);
            curl_easy_cleanup(curl);
            return "0";
        }
        code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
        if (code != CURLE_OK)
        {
            fprintf(stderr, "Failed to set 2 [%d]\n", code);
            curl_easy_cleanup(curl);
            return "0";
        }
        code = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
        if (code != CURLE_OK)
        {
            fprintf(stderr, "Failed to set 3 [%d]\n", code);
            curl_easy_cleanup(curl);
            return "0";
        }
        code = curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2);
        if (code != CURLE_OK)
        {
            fprintf(stderr, "Failed to set 4 [%d]\n", code);
            curl_easy_cleanup(curl);
            return "0";
        }
        code = curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
        if (code != CURLE_OK)
        {
            fprintf(stderr, "Failed to set 5 [%d]\n", code);
            curl_easy_cleanup(curl);
            return "0";
        }
        code = curl_easy_perform(curl);
        if (code != CURLE_OK)
        {
            fprintf(stderr, "Failed to get [%d]\n", code);
            curl_easy_cleanup(curl);
            return "0";
        }
        //清除curl操作.
        curl_easy_cleanup(curl);
        return buffer;
    }
    return "";
}

bool isValidTime()
{
    time_t rawtime;
    struct tm * timeinfo;

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    if (timeinfo->tm_hour < 9)
        return false;
    if (timeinfo->tm_hour == 9 && timeinfo->tm_min >= 15)
        return true;
    if (timeinfo->tm_hour > 9 && timeinfo->tm_hour <= 10)
        return true;
    if (timeinfo->tm_hour == 11 && timeinfo->tm_min <= 30)
        return true;
    if (timeinfo->tm_hour == 11 && timeinfo->tm_min > 30)
        return false;

    if (timeinfo->tm_hour == 12)
        return false;
    if (timeinfo->tm_hour >= 13 && timeinfo->tm_hour < 15)
        return true;
    //if (timeinfo->tm_hour >= 15)
    //    return false;
    if (timeinfo->tm_hour == 15 && timeinfo->tm_min < 30)
        return true;
    return false;
}

int main(int argc, char* argv[])
{
//    curl_global_init(CURL_GLOBAL_ALL);
    getAll(argv[1]);
    return 0;
}

bool getAll(const char* stockList)
{
    ifstream iFile(stockList);
    if (!iFile)
    {
        cerr << "open file error: " << stockList << endl;
        return false;
    }
    string line;
    vector<string> stockVector;
    vector<ofstream *> oFileVector;
    vector<ofstream *> oFile5TimesVector;
    vector<ofstream *> oFile400Vector;

    time_t rawtime;
    struct tm * timeinfo;

    time(&rawtime);
    timeinfo = localtime(&rawtime);
    char date[20] = {0};
    sprintf(date, "%4d-%02d-%02d", 1900 + timeinfo->tm_year, 1 + timeinfo->tm_mon, timeinfo->tm_mday);

    while(getline(iFile, line))
    {
        if (line != "")
        {
            string cmd = "mkdir -p ../data/buy_sell/" + line + "/" + date;
            system(cmd.c_str());
            stockVector.push_back(line);
        
            string fileName = "../data/buy_sell/" + line + "/" + date + "/buy_sell";
            ofstream *ofs = new ofstream(fileName.c_str(), ios::app);
            if (!(*ofs))
            {
                cerr << "open file for write error: " << line << endl;
                return false;
            }
            oFileVector.push_back(ofs);
            
            //5times and 400
            cmd = "mkdir -p ../data/5times_400/" + line + "/";
            system(cmd.c_str());
        
            string fileName5Times = "../data/5times_400/" + line + "/" + date + ".5times";
            ofstream *ofs5Times = new ofstream(fileName5Times.c_str());
            if (!(*ofs5Times))
            {
                cerr << "open file for write error: " << line << endl;
                return false;
            }
            oFile5TimesVector.push_back(ofs5Times);

            string fileName400 = "../data/5times_400/" + line + "/" + date + ".400";
            ofstream *ofs400 = new ofstream(fileName400.c_str());
            if (!(*ofs400))
            {
                cerr << "open file for write error: " << line << endl;
                return false;
            }
            oFile400Vector.push_back(ofs400);
        }
    }
    iFile.close();

    while(isValidTime())
    {
        for (size_t i = 0; i < stockVector.size(); ++i)
        {
            string line = GetResponseByCurl("http://hq.sinajs.cn/list=" + stockVector[i]);
            (*(oFileVector[i])) << line;
            oFileVector[i]->flush();
            
            line = GetResponseByCurl("http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_Bill.GetBillList?symbol=" + stockVector[i] + "&num=6000&page=1&sort=ticktime&asc=0&volume=40000&type=0&day=" + date);
            (*(oFile400Vector[i])) << line;
            oFile400Vector[i]->flush();
            
            line = GetResponseByCurl("http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_Bill.GetBillList?symbol=" + stockVector[i] + "&num=6000&page=1&sort=ticktime&asc=0&volume=0&type=1&day=" + date);
            (*(oFile5TimesVector[i])) << line;
            oFile5TimesVector[i]->flush();
        }
        cout << "sleep" << endl;
        sleep(10);
    }

    for (size_t i = 0; i < oFileVector.size(); ++i)
    {
        oFileVector[i]->close();
        delete oFileVector[i];
    }
    
    for (size_t i = 0; i < oFile400Vector.size(); ++i)
    {
        oFile400Vector[i]->close();
        delete oFile400Vector[i];
        oFile5TimesVector[i]->close();
        delete oFile5TimesVector[i];
    }
    return true;
}
